package models;

import java.util.Date;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Table;
import javax.persistence.Transient;

import net.ufrog.common.Logger;
import net.ufrog.common.utils.Strings;
import play.cache.Cache;
import play.mvc.Scope.Session;
import utils.dict.Element;
import weixin.WXRequest;
import weixin.resp.UserInfo;

/**
 * 用户模型
 * 
 * @author ultrafrog
 * @version 1.0, 2014-11-03
 * @since 1.0
 */
@Entity
@Table(name = "uwx_user")
public class User extends Model {

	private static final String SESSION_USER	= "play_weixin_session_user";
	private static final String CACHE_PREFIX	= "play_weixin_cache_user_";
	
	/** 微信号 */
	@Column(name = "vc_open_id")
	public String openId;
	
	/** 邮件 */
	@Column(name = "vc_email")
	public String email;
	
	/** 手机 */
	@Column(name = "vc_cellphone")
	public String cellphone;
	
	/** 昵称 */
	@Column(name = "vc_nickname")
	public String nickname;
	
	/** 密码 */
	@Column(name = "vc_password")
	public String password;
	
	/** 状态 */
	@Column(name = "dc_status")
	public String status;
	
	/** 类型 */
	@Column(name = "dc_type")
	public String type;
	
	/** 公众号 */
	@Column(name = "fk_weixin")
	public String weixin;
	
	/** 属性 */
	@Transient
	public UserProp prop;
	
	/** 构造函数 */
	public User() {}
	
	/**
	 * 构造函数 
	 * 
	 * @param openId
	 * @param status
	 * @param type
	 * @param weixin
	 */
	public User(String openId, String status, String type, String weixin) {
		this();
		this.openId = openId;
		this.status = status;
		this.type = type;
		this.weixin = weixin;
	}
	
	/**
	 * 通过微信号加载用户
	 * 
	 * @param openId
	 * @return
	 */
	public static User loadByOpenId(String openId) {
		return find("byOpenId", openId).first();
	}
	
	/**
	 * 通过编号读取用户<br>
	 * 优先从缓存读取数据
	 * 
	 * @param id
	 * @return
	 */
	public static User getById(String id) {
		User user = Cache.get(CACHE_PREFIX + id, User.class);
		if (user == null) {
			user = findById(id);
			Cache.add(CACHE_PREFIX + id, user);
		}
		return user;
	}
	
	/**
	 * 保存微信用户
	 * 
	 * @param weixin
	 * @param openId
	 * @return
	 */
	public static User saveByWeixin(String weixin, String openId) {
		// 查询用户
		User user = User.find("byOpenId", openId).first();
		UserProp userProp = null;
		
		// 判断用户是否存在
		if (user != null) {
			user.status = User.Status.ENABLED;
			userProp = UserProp.find("byUser", user.id).first();
		} else {
			user = new User(openId, User.Status.ENABLED, User.Type.CLIENT, weixin);
			userProp = new UserProp();
		}
		
		// 保存用户
		UserInfo userInfo = WXRequest.User.info(Weixin.getById(weixin), user.openId);
		user.save();
		userProp.subscribe = userInfo.subscribe;
		userProp.nickname = userInfo.nickname;
		userProp.sex = userInfo.sex;
		userProp.country = userInfo.country;
		userProp.province = userInfo.province;
		userProp.city = userInfo.city;
		userProp.language = userInfo.language;
		userProp.headImgUrl = userInfo.headimgurl;
		userProp.subscribeTime = new Date(userInfo.subscribeTime * 1000);
		userProp.unionId = userInfo.unionid;
		userProp.user = user.id;
		userProp.save();
		
		// 返回结果
		return user;
	}
	
	/**
	 * 设置当前用户编号
	 * 
	 * @param id
	 * @return
	 */
	public static String currentId(String id) {
		Session.current().put(SESSION_USER, id);
		return id;
	}

	/**
	 * 读取当前用户编号
	 * 
	 * @return
	 */
	public static String currentId() {
		try {
			return Session.current().get(SESSION_USER);
		} catch (Exception e) {
			Logger.warn("cannot get current user id, for reason: %s", e.getMessage());
			return null;
		}
	}
	
	/**
	 * 读取当前用户
	 * 
	 * @return
	 */
	public static User current() {
		if (Strings.empty(currentId())) {
			return null;
		}
		return getById(currentId());
	}
	
	/**
	 * 状态
	 * 
	 * @author ultrafrog
	 * @version 1.0, 2014-11-03
	 * @since 1.0
	 */
	public static class Status {
		
		@Element("有效")
		public static final String ENABLED	= "01";
		
		@Element("冻结")
		public static final String FROZEN	= "80";
		
		@Element("注销")
		public static final String DISABLED	= "99";
	}
	
	/**
	 * 类型
	 * 
	 * @author ultrafrog
	 * @version 1.0, 2014-11-03
	 * @since 1.0
	 */
	public static class Type {
		
		@Element("客户")
		public static final String CLIENT	= "01";
		
		@Element("管理员")
		public static final String ADMIN	= "90";
		
		@Element("根")
		public static final String ROOT		= "99";
	}
}
